home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / sort.arc / sortfile.c < prev    next >
C/C++ Source or Header  |  1989-03-30  |  8KB  |  279 lines

  1. /******************************************************************************
  2.  *                                                                            *
  3.  *   sortfile.c  version 1.0 of  1 Januari 1989    (C) L.J.M. de Wit 1989     *
  4.  *                                                                            *
  5.  * This software may be used and distributed freely if not used commercially  *
  6.  * and the originator (me) is mentioned in the source (just leave this 9 line *
  7.  * header intact).                                                            *
  8.  *                                                                            *
  9.  ******************************************************************************
  10.  *
  11.  * sortfile.c: stdio replacement for Atari ST
  12.  *
  13.  * This replacement is added both to speed up the normal stdio offered by
  14.  * Lattice C, and to repair a bug with open() (fopen() ?) that is in the
  15.  * standard library (version 3.03: try opening & closing 20 files, your
  16.  * program bombs when you try to open a new file, even though the old ones
  17.  * have been closed).
  18.  *
  19.  * Note that this package is not complete (no flushbuf, filbuf, printf etc.)
  20.  * but this wasn't the intent anyway; furthermore, the allocation of buffers
  21.  * takes place when a file is opened, rather than when it is first read/written
  22.  * (as in a standard stdio package).
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <osbind.h>
  27. #include <fcntl.h>
  28. #include "sortmain.h"
  29. #include "sortfile.h"
  30.  
  31. #undef  Fwrite
  32. #define Fwrite fixwrite                         /* Fix for Fwrite bug       */
  33.  
  34. static int buflen;                              /* Default buffer length    */
  35.  
  36. static int lopen();
  37. static int fixwrite();
  38.  
  39. #ifdef BESTIO
  40.  
  41. void bestio(size)                               /* Initializes stdin/stdout */
  42. int size;
  43. {
  44.     char *iobuffer[2];                          /* stdin/stdout buffer ptrs */
  45.  
  46.     buflen = size;
  47.     iobuffer[0] = (char *)Malloc(buflen);
  48.     iobuffer[1] = (char *)Malloc(buflen);
  49.     if (iobuffer[0] == (char *)-1 || iobuffer[1] == (char *)-1) {
  50.         error("memory allocation failed\n",(char *)0);
  51.     }
  52.     stdin->_ptr   = stdin->_base = iobuffer[0];
  53.     stdin->_rcnt  = buflen;
  54.     stdin->_flag  = _IOREAD;
  55.     stdin->_file  = 0;
  56.     stdin->_size  = buflen;
  57.  
  58.     stdout->_ptr  = stdout->_base = iobuffer[1];
  59.     stdout->_wcnt = buflen;
  60.     stdout->_flag = _IOWRT;
  61.     stdout->_file = 1;
  62.     stdout->_size = buflen;
  63. }
  64.  
  65. void exit(code)                                 /* Replaces standard exit   */
  66. int code;
  67. {
  68.     int i;
  69.  
  70.     for (i = 0; i < _NFILE; i++) {
  71.         if (_iob[i]._flag != 0) {               /* Stclose any open files   */
  72.             stclose(_iob+i);
  73.         }
  74.     }
  75.     _exit(code);                                /* and _exit                */
  76. }
  77.  
  78. #else NOT BESTIO
  79.  
  80. int _fmode = 0x8000;                            /* No translation, for speed*/
  81.  
  82. #endif BESTIO
  83.  
  84. FILE *stopen(filename,mode)                     /* Replaces fopen()         */
  85. char *filename, *mode;
  86. {
  87.     FILE *fp;
  88.     int desc;
  89.     int flag;
  90.     int i;
  91.  
  92.     for (i = 0; i < _NFILE; i++) {              /* Find first free entry    */
  93.         if (_iob[i]._flag == 0) {
  94.             break;
  95.         }
  96.     }
  97.     if (i < _NFILE) {
  98.         fp = _iob + i;                          /* First free               */
  99.     } else {
  100.         return (FILE *)0;                       /* All occupied             */
  101.     }
  102.  
  103.     if (!strcmp(mode,"w")) {                    /* Mode "w": write          */
  104.         desc = lopen(filename,O_WRONLY|O_CREAT|O_TRUNC);
  105.         flag = _IOWRT;
  106.     } else if (!strcmp(mode,"r")) {             /* Mode "r": read           */
  107.         desc = lopen(filename,O_RDONLY);
  108.         flag = _IOREAD;
  109.     } else {                                    /* Unknown mode             */
  110.         return (FILE *)0;
  111.     }
  112.  
  113.     if (desc < 0) {
  114.         return (FILE *)0;                       /* Lopen failed             */
  115.     } else {
  116.         fp->_rcnt = fp->_wcnt = fp->_size = 0;
  117.         fp->_ptr  = fp->_base = (char *)0;
  118.         fp->_file = desc;
  119.         fp->_flag = flag;
  120.     }
  121.  
  122.     return fp;
  123. }
  124.  
  125. int stclose(fp)                                 /* Replaces fclose()        */
  126. FILE *fp;
  127. {
  128.     int retco;
  129.  
  130.     if (fp->_flag & (_IORW|_IOWRT)) {
  131.         stflush(fp);                            /* Flush an output stream   */
  132.     }
  133.     retco = Fclose(fp->_file);                  /* Close file               */
  134.     if (fp->_base != (char *)0) {
  135.         retco |= Mfree(fp->_base);               /* Free allocated buffer    */
  136.     }
  137.     fp->_base = (char *)0;
  138.     fp->_flag = 0;                              /* Indicate entry is free   */
  139.  
  140.     return retco;
  141. }
  142.  
  143. int stflush(fp)
  144. FILE *fp;
  145. {
  146.     if (fp->_size > fp->_wcnt) {                /* Any data to be flushed ? */
  147.         Fwrite(fp->_file,fp->_size-fp->_wcnt,fp->_base); /* Write it        */
  148.         fp->_ptr = fp->_base;                   /* re-init ptr              */
  149.         fp->_wcnt = fp->_size;                  /* and _wcnt                */
  150.     }
  151. }
  152.  
  153. void stbuffer(fp,buf,size)
  154. FILE *fp;
  155. char *buf;
  156. int size;
  157. {
  158.     fp->_ptr = fp->_base = buf;
  159.     fp->_size = size;
  160.     fp->_wcnt = size;
  161.     fp->_rcnt = 0;
  162. }
  163.  
  164. char *stgets(inbuf,size,fp)                     /* Replaces fgets()         */
  165. char *inbuf;
  166. register int size;
  167. register FILE *fp;
  168. {
  169.     register int todo, i, ntoread;
  170.     register char *s, *t;
  171.  
  172.     if (fp->_base == (char *)0) {
  173.         s = (char *)Malloc(buflen);             /* Allocate buffer   */
  174.         stbuffer(fp,s,buflen);
  175.     }
  176.     if (size-- <= 0 || feof(fp)) {              /* One for the '\0'         */
  177.         return (char *)0;
  178.     }
  179.  
  180.     t = inbuf;
  181.     s = fp->_ptr;
  182.     ntoread = fp->_rcnt;
  183.  
  184.     for ( ; ; ) {
  185.         todo = min(size,ntoread);
  186.         for (i = 0; i < todo; i++) {
  187.             if ((*t++ = *s++) == '\n') {        /* Had a newline            */
  188.                 i++;
  189.                 *t = '\0';                      /* 0-terminate line         */
  190.                 fp->_ptr = s;
  191.                 fp->_rcnt = ntoread - i;
  192.                 return inbuf;
  193.             }
  194.         }
  195.         if ((size -= todo) <= 0) {              /* All read                 */
  196.             break;
  197.         }
  198.         ntoread = Fread(fp->_file,fp->_size,fp->_base); /* Read a buffer    */
  199.         s = fp->_base;                          /* Re-init ptr              */
  200.         if (ntoread <= 0) {
  201.             fp->_flag |= _IOEOF;
  202.             return (char *)0;                   /* End-of-file */
  203.         }
  204.     }
  205.     fp->_rcnt = ntoread - todo;
  206.     fp->_ptr = s;
  207.     *t = '\0';
  208.     return inbuf;
  209. }
  210.  
  211. void stputs(inbuf,fp)                           /* Replaces fputs()         */
  212. char *inbuf;
  213. register FILE *fp;
  214. {
  215.     register int i, ntowrite;
  216.     register char *s, *t;
  217.  
  218.     if (fp->_base == (char *)0) {
  219.         s = (char *)Malloc(buflen);             /* Allocate buffer   */
  220.         stbuffer(fp,s,buflen);
  221.     }
  222.     s = inbuf;
  223.     t = fp->_ptr;
  224.     ntowrite = fp->_wcnt;
  225.  
  226.     for ( ; ; ) {
  227.         for (i = 0; i < ntowrite; i++) {
  228.             if (*s == '\0') {                   /* Found 0 terminator       */
  229.                 break;
  230.             }
  231.             *t++ = *s++;
  232.         }
  233.         if (*s == '\0') {
  234.             fp->_wcnt = ntowrite - i;
  235.             fp->_ptr = t;
  236.             return;
  237.         }
  238.         Fwrite(fp->_file,t - fp->_base,fp->_base); /* Write a buffer        */
  239.         ntowrite = fp->_size;
  240.         t = fp->_base;                          /* Re-init ptr              */
  241.     }
  242. }
  243.  
  244. static int lopen(filename,mode)                 /* Simple open() replacement*/
  245. char *filename;
  246. int mode;
  247. {
  248.     int fd;
  249.  
  250.     if (!(mode & O_TRUNC)) {
  251.         fd = Fopen(filename,mode & (O_WRONLY|O_RDWR));      /* Open file    */
  252.     }
  253.  
  254.     if ((mode & O_TRUNC) || ((fd < 0) && (mode & O_CREAT))) {
  255.         fd = Fcreate(filename,!(mode & (O_WRONLY|O_RDWR))); /* Create file  */
  256.     }
  257.  
  258.     return fd;
  259. }
  260.  
  261. static int fixwrite(fd,len,buf)
  262. int fd, len;
  263. char *buf;
  264. {
  265.     int total, piece = 0;
  266.     char *top;
  267.  
  268.     if (fd != 1) {
  269.         return gemdos(0x40,fd,len,buf);
  270.     }
  271.     for (total = 0, top = buf + len; len > 0; buf += piece, len -= piece) {
  272.         if ((piece = len) > 32767) {
  273.             piece = 32256;
  274.         }
  275.         total += gemdos(0x40,fd,pi